<template>
    <div ref="propertyPanel" class="property-panel">
        <a-collapse v-model="activeName" accordion expandIconPosition="left" style="border-left: none;border-top: none;border-right: none">
            <a-collapse-panel key="1">
                <span slot="header"><a-icon type="setting"/> 基本设置</span>
                <div v-if="!isSendTask&&!isReceiveTask&&!isTask">
                    <a-form-model :model="form" ref="processForm" :rules="rules" :label-col="labelCol" :wrapper-col="wrapperCol">
                        <a-form-model-item label="流程类型" v-if="isRoot">
                            <a-select v-model="processTypeId" placeholder="请选择流程类型" @change="processTypeChange">
                                <a-select-option v-for="item in processType" :key="item.value" :value="item.value">
                                    {{item.label}}
                                </a-select-option>
                            </a-select>
                        </a-form-model-item>
                        <a-form-model-item label="流程key" v-if="isRoot">
                            <a-input v-model="process.id" allow-clear placeholder="请输入processKey" @input="updateProcessKey"/>
                        </a-form-model-item>

                        <a-form-model-item label="流程名称" v-if="isRoot">
                            <a-input v-model="process.name" allow-clear placeholder="请输入流程名称" @input="updateProcessName"/>
                        </a-form-model-item>

                        <a-form-model-item label="描述" v-if="isRoot">
                            <a-input v-model="process.description" :rows="3" type="textarea" allow-clear placeholder="请输入描述" @input="updateProcessDocumentation"/>
                        </a-form-model-item>

                        <a-form-model-item label="节点key" prop="id" v-if="!isRoot">
                            <a-input v-model="form.id" allow-clear placeholder="请输入key" @input="updateKey"/>
                        </a-form-model-item>
                        <a-form-model-item label="节点名称" prop="name" v-if="!isRoot">
                            <a-input v-model="form.name" allow-clear placeholder="请输入名称" @input="updateName"/>
                        </a-form-model-item>
                        <!--          <a-form-model-item label="节点大小" prop="size" v-if="!isRoot&&isUserTask">-->
                        <!--            <a-radio-group v-model="nodeSize"   @change="handleSizeChange">-->
                        <!--              <a-radio-button value="large">大</a-radio-button>-->
                        <!--              <a-radio-button value="small">小</a-radio-button>-->
                        <!--            </a-radio-group>-->
                        <!--          </a-form-model-item>-->
                        <!--服务任务-->
                        <a-form-model-item label="执行类型" prop="name" v-if="!isRoot&&isServiceTask">
                            <a-input-group compact style="width: 310px">
                                <a-select style="width: 100px" v-model="serviceTask.expressionType" @change="updateExpressionValue">
                                    <a-select-option value="javaClass">
                                        <a-tooltip placement="left" title="javaClass">javaClass</a-tooltip>
                                    </a-select-option>
                                    <a-select-option value="expression">
                                        <a-tooltip placement="left" title="expression">expression</a-tooltip>
                                    </a-select-option>
                                    <a-select-option value="delegateExpression">
                                        <a-tooltip placement="left" title="delegateExpression">delegateExpression</a-tooltip>
                                    </a-select-option>
                                </a-select>
                                <a-input style="width: 50%" v-model="serviceTask.expressionValue" @input="updateExpressionValue"/>
                            </a-input-group>
                        </a-form-model-item>

                        <a-form-model-item label="结果变量" prop="name" v-if="!isRoot&&isServiceTask">
                            <a-input v-model="form.resultVariableName" allow-clear placeholder="请输入执行结果变量" @input="updateProperties({resultVariableName: form.resultVariableName || undefined})"/>
                        </a-form-model-item>

                        <!--脚本任务-->
                        <a-form-model-item label="脚本类型" v-if="!isRoot&&isScriptTask">
                            <a-select v-model="form.scriptFormat" placeholder="请选择脚本类型" @change="scriptTypeChange">
                                <a-select-option v-for="item in scriptType" :key="item.value" :value="item.value">
                                    {{item.label}}
                                </a-select-option>
                            </a-select>
                        </a-form-model-item>

                        <a-form-model-item label="脚本内容" v-if="!isRoot&&isScriptTask">
                            <a-input v-model="form.script" :rows="3" type="textarea" allow-clear placeholder="请输入脚本内容" @input="updateScript"/>
                        </a-form-model-item>

                        <a-form-model-item label="子流程" v-if="isCallActivity">
                            <a-input v-model="form.calledElement" allow-clear placeholder="请输入子流程名称" @input="updateProperties({calledElement: form.calledElement || undefined})"/>
                        </a-form-model-item>


                        <!--规则任务-->
                        <a-form-model-item label="输入变量" v-if="!isRoot&&isBusinessRuleTask">
                            <a-input v-model="form.ruleVariablesInput" allow-clear placeholder="请填写输入变量" @input="updateProperties({ruleVariablesInput: form.ruleVariablesInput || undefined})"/>
                        </a-form-model-item>
                        <a-form-model-item label="输出变量" v-if="!isRoot&&isBusinessRuleTask">
                            <a-input v-model="form.resultVariable" allow-clear placeholder="请填写输出变了" @input="updateProperties({resultVariable: form.resultVariable || undefined})"/>
                        </a-form-model-item>

                        <!--          <a-form-model-item label="除外" v-if="!isRoot&&isBusinessRuleTask">-->
                        <!--            <a-radio-group name="radioGroup" v-model="form.exclude" :default-value="true" @input="updateProperties({exclude: null || undefined})">-->
                        <!--              <a-radio value="true">是</a-radio>-->
                        <!--              <a-radio value="false">否</a-radio>-->
                        <!--            </a-radio-group>-->
                        <!--          </a-form-model-item>-->

                        <a-form-model-item label="规则" v-if="!isRoot&&isBusinessRuleTask">
                            <a-input v-model="form.rules" allow-clear placeholder="请填写规则" @input="updateProperties({rules: form.rules || undefined})"/>
                        </a-form-model-item>

                        <!--定时边界任务-->
                        <a-form-model-item label="事件类型" v-if="!isRoot&&isBoundaryEvent">
                            <a-select v-model="boundaryEvent.timerType" placeholder="请选择事件类型" @change="timerEventTypeChange">
                                <a-select-option v-for="item in timerEventType" :key="item.value" :value="item.value">
                                    {{item.label}}
                                </a-select-option>
                            </a-select>
                        </a-form-model-item>

                        <a-form-model-item label="时间" v-if="!isRoot&&isBoundaryEvent">
                            <a-input v-model="form.timeDate" allow-clear placeholder="请填写时间规则" @input="timerEventTypeChange"/>
                        </a-form-model-item>

                        <a-form-model-item label="描述" v-if="!isRoot">
                            <a-input v-model="form.description" :rows="3" type="textarea" allow-clear placeholder="请输入描述" @input="updateDocumentation"/>
                        </a-form-model-item>
                        <a-alert message="配置说明" v-if="!isRoot&&isServiceTask">
                            <p slot="description">
                                1.服务任务，当流程执行到服务任务时，执行相应的服务内容。<br/>
                                2.执行类型参数配置<br/>
                                <span style="margin-left: 13px;">javaClass:执行java类</span><br/>
                                <span style="margin-left: 13px;">expression:表达式</span><br/>
                                <span style="margin-left: 13px;"> delegateExpression:Spring容器中bean</span><br/>
                                3.返回变量：任务返回处理结果保存到流程变量中的变量名称。<br/>
                            </p>
                        </a-alert>

                        <a-alert message="配置说明" v-if="!isRoot&&isScriptTask">
                            <p slot="description">
                                1.脚本任务，当流程执行到脚本任务时，执行相应的脚本。<br/>
                                2.默认脚本变量不自动保存到流程变量，需在脚本中调用:execution.setVariable("myVar",val)保存到流程变量。<br/>
                                3.脚本内容需要和脚本格式对应。<br/>
                            </p>
                        </a-alert>

                        <a-alert message="事件类型配置说明" v-if="!isRoot&&isBoundaryEvent">
                            <p slot="description">
                                1.timeDate:触发事件的时间,示例值:2020-03-11 12:13:14<br/>
                                2.timeDuration:指定定时器之前要等待多长时间,使用ISO 8601规定的格式 （由BPMN 2.0规定）,示例值P1D(等待一天),也支持表达式${duration},这样你就可以通过流程变量来影响那个定时器定义<br/>
                                3.timeCycle:指定重复执行的间隔， 可以用来定期启动流程实例，或为超时时间发送多个提醒。 timeCycle元素可以使用两种格式。第一种是 ISO 8601 标准的格式。示例值(R3/PT10H)(重复3次，每次间隔10小时),或者，你可以使用cron表达式指定timeCycle，下面的例子是从整点开始，每5分钟执行一次(0 0/5 * * * ?)<br/>
                            </p>
                        </a-alert>


                        <div v-if="isRoot" style="display: none;">
                            <a-form-model-item label="版本号" prop="processVersion">
                                <a-input v-model="form.versionTag" allow-clear placeholder="请输入版本号" @input="updateProperties({versionTag: form.versionTag || undefined})"/>
                            </a-form-model-item>
                            <a-form-model-item label="任务级别">
                                <a-input v-model="form.taskPriority" allow-clear placeholder="请输入任务优先级" @input="updateProperties({taskPriority: form.taskPriority || undefined})"/>
                            </a-form-model-item>
                            <a-form-model-item label="工作级别">
                                <a-input v-model="form.jobPriority" allow-clear placeholder="请输入工作优先级" @input="updateProperties({jobPriority: form.jobPriority || undefined})"/>
                            </a-form-model-item>
                            <a-form-model-item label="保留时间">
                                <a-input v-model="form.historyTimeToLive" allow-clear placeholder="请输入保留时间" @input="updateProperties({historyTimeToLive: form.historyTimeToLive || undefined})"/>
                            </a-form-model-item>
                            <a-form-model-item label="颜色" v-if="!isRoot">
                                <a-input placeholder="设置节点颜色" style="height:250px" v-model="userTask.color" disabled="">
                                    <colorPicker slot="addonBefore" v-model="userTask.color" @change="updateColor"/>
                                </a-input>
                            </a-form-model-item>
                        </div>
                    </a-form-model>
                </div>
                <div v-else>
                    <a-alert message="该组件暂不支持">

                    </a-alert>
                </div>
            </a-collapse-panel>
            <a-collapse-panel key="2" v-if="isUserTask">
                <span slot="header"><a-icon type="user"/> 审核者</span>
                <a-form-model ref="userTaskForm" :model="userTask" :label-col="labelCol" :wrapper-col="wrapperCol" size="small">
                    <a-form-model-item label="用户类型">
                        <a-select v-model="selectUserType" placeholder="请选用户类型" @change="">
                            <a-select-option v-for="item in userType" :key="item.value" :value="item.value">
                                {{item.label}}
                            </a-select-option>
                        </a-select>
                    </a-form-model-item>

                    <!--          <a-form-model-item label="类型">-->
                    <!--            <a-radio-group v-model="userTask.assigneeType" @change="handleChangeAssignee">-->
                    <!--              <a-radio value="1">指定用户</a-radio>-->
                    <!--              <a-radio value="2">表达式</a-radio>-->
                    <!--            </a-radio-group>-->
                    <!--          </a-form-model-item>-->
                    <a-form-model-item v-if="selectUserType === 'assignee'" label="处理人">
                        <a-input v-model="userTask.assigneeName" allowClear placeholder="请选择处理人" @input="handleUserChange">
                            <a-icon slot="addonAfter" type="user" @click="handleSelectUser(false, 'assignee')"/>
                            <a-divider type="vertical" slot="addonAfter"/>
                            <a-icon slot="addonAfter" type="calculator" @click="handleSelectExpressions(false, 'assignee')"/>
                        </a-input>
                    </a-form-model-item>
                    <a-form-model-item v-if="selectUserType === 'candidateUsers'" label="候选用户">
                        <a-input v-model="userTask.candidateUsersName" allowClear  placeholder="请选择候选用户" @input="handleUsersChange">
                            <a-icon slot="addonAfter" type="solution" @click="handleSelectUser(true, 'candidateUsers')"/>
                            <a-divider type="vertical" slot="addonAfter"/>
                            <a-icon slot="addonAfter" type="calculator" @click="handleSelectExpressions(false, 'candidateUsers')"/>
                        </a-input>
                    </a-form-model-item>
                    <a-form-model-item v-if="selectUserType === 'candidateGroups'" label="候选角色">
                        <a-input v-model="userTask.candidateGroups" allowClear placeholder="请选择候选角色" @input="handleRoleChange">
                            <a-icon slot="addonAfter" type="team" @click="handleSelectRoles(true, 'candidateGroups')"/>
                            <a-divider type="vertical" slot="addonAfter"/>
                            <a-icon slot="addonAfter" type="calculator" @click="handleSelectExpressions(false, 'candidateGroups')"/>
                        </a-input>
                    </a-form-model-item>
                    <!--          <a-form-model-item v-if="userTask.assigneeType === '2'" label="表达式">-->
                    <!--            <a-input v-model="userTask.expressions" allowClear placeholder="请选择表达式" @input="handleExpressionsUpdate">-->
                    <!--              <a-icon slot="addonAfter" type="calculator" @click="handleSelectExpressions(false, 'assignee')"/>-->
                    <!--            </a-input>-->
                    <!--          </a-form-model-item>-->
                </a-form-model>
            </a-collapse-panel>
            <a-collapse-panel key="3" v-if="(isStart || isTask)" style="display: none">
                <span slot="header"><a-icon type="form"/> 表单设置</span>
                <a-form-model :model="userTask" ref="formKeyForm" :label-col="labelCol" :wrapper-col="wrapperCol">
                    <a-form-model-item label="表单key" prop="formKey">
                        <a-input v-model="userTask.formKey" allowClear placeholder="请输入表单key" @input="updateFormKey"/>
                    </a-form-model-item>
                </a-form-model>
            </a-collapse-panel>
            <a-collapse-panel key="4" v-if="isUserTask||!isRoot" style="display: none">
                <span slot="header"><a-icon type="appstore"/> 按钮配置</span>
                <div class="el_title">
                    <a-button type="primary" size="small" @click="addButton()">选择</a-button>
                    <a-table v-if="buttonsData.length > 0" :data="buttonsData" border style="width: 90%; margin-top: 5px;">
                        <a-table-column data-index="name" title="名称" align="center"/>
                        <a-table-column title="操作" align="center" width="100px">
                            <template slot-scope="scope">
                                <a-button size="small" type="text" @click="removeButton(scope.row)">删除</a-button>
                            </template>
                        </a-table-column>
                    </a-table>
                </div>
            </a-collapse-panel>
            <a-collapse-panel key="5" v-if="isUserTask ||isCallActivity" tab="会签属性">
                <span slot="header"><a-icon type="team"/> 会签配置</span>
                <a-form-model ref="multiInstanceForm" :model="selectedMultiInstance" :label-col="labelCol" :wrapper-col="wrapperCol" size="small">
                    <a-form-model-item label="类型">
                        <a-select v-model="selectedMultiInstanceNew.isSequential" allowClear placeholder="请选择" @change="handleMultiInstance">
                            <a-select-option v-for="item in multiInstanceOptions" :key="item.value" :value="item.value">
                                {{item.label}}
                            </a-select-option>
                        </a-select>
                    </a-form-model-item>
                    <div>
                        <a-form-model-item label="循环数量">
                            <a-input v-model="selectedMultiInstanceNew.loopCardinality" allowClear placeholder="请输入循环数量" @input="updateFormalExpression('loopCardinality',selectedMultiInstanceNew.loopCardinality)"/>
                        </a-form-model-item>
                        <a-form-model-item label="循环集合">
                            <a-input v-model="selectedMultiInstanceNew.collection" allowClear placeholder="请输入集合" @input="updateMultiInstanceProperty(moddleType+':collection', selectedMultiInstanceNew.collection)"/>
                        </a-form-model-item>
                        <a-form-model-item label="元素变量">
                            <a-input v-model="selectedMultiInstanceNew.elementVariable" allowClear placeholder="请输入元素变量" @input="updateMultiInstanceProperty(moddleType+':elementVariable', selectedMultiInstanceNew.elementVariable)"/>
                        </a-form-model-item>
                        <a-form-model-item label="完成条件">
                            <a-input v-model="selectedMultiInstanceNew.completionCondition" allowClear placeholder="请输入完成条件" @input="updateFormalExpression('completionCondition',selectedMultiInstanceNew.completionCondition)"/>
                        </a-form-model-item>
                    </div>
                    <a-tooltip placement="topLeft" overlayClassName="overlayClassName">
            <span slot="title" style="width:600px">
              1.${flowUtil.stringToList(assigneeUserIdList)}，将字符串转换成集合，暴露的SpringBean方法<br>
2.多实例任务Activiti默认会创建3个流程变量，nrOfInstances:实例总数，nrOfActiveInstances:当前活跃的，也就是当前还未完成的，对于顺序的多实例，此值总是1,nrOfCompletedInstances:已完成的实例个数。<br>
3.状态:不启动多实例,则只会创建一个任务，默认不启动，不启动多实例，一下配置都无效，true:顺序执行，fasle:并行,同时执行。<br>
4.循环数量:指定创建多任务的数量。可使用表达式从流程变量获取。<br>
5.循环集合:流程变量中一个集合类型变量的变量名称。根据集合元素多少创建任务数量。可使用表达式。例:流程变量：assigneeUserIdList=[user1,user2]，可用assigneeUserIdList。<br>
6.集合元素:集合中每个元素的变量名称，可在每个任务中获取,可使用表达式。例：集合为当定义集合元素名称为:assigneeUserId,可在任务直接指派人员用表达式${assigneeUserId}获取，用于动态会签。<br>
7.结束条件:多实例活动结束的条件，默认为完成多全部实例，当表达式返回true时结束多实例活动。例：${nrOfCompletedInstances/nrOfInstances>=0.6} 说明当有60%的任务完成时，会完成此多实例，删除其他未完成的，继续下面的流程。<br>
            </span>
                        <a-alert message="使用说明" banner/>
                    </a-tooltip>
                </a-form-model>
            </a-collapse-panel>
            <a-collapse-panel key="6" v-if="isExclusiveSequenceFlow">
                <span slot="header"><a-icon type="share-alt"/> 流转条件</span>
                <template slot="title">
                    <span class="el_title"></span>
                </template>
                <a-form-model ref="userTaskForm" :model="exclusiveSequence" label-width="100px" size="small">
                    <a-form-model-item label="表达式">
                        <a-input v-model="exclusiveSequence.conditionExpression" allowClear placeholder="请输入表达式" @input="updateConditionExpression">
                            <a-button slot="append" icon="el-icon-plus"/>
                        </a-input>
                    </a-form-model-item>
                </a-form-model>
            </a-collapse-panel>
            <a-collapse-panel key="7" v-if="!isGateway&&!isServiceTask&&!isScriptTask&&!isBoundaryEvent&&!isSendTask&&!isReceiveTask&&!isTask">
                <span slot="header"><a-icon type="notification"/> 执行监听</span>
                <a-icon slot="extra" type="plus" @click.stop="addListeners(false)"/>
                <a-table :dataSource="listenerData" rowKey="id" :columns="listenerColumns" :bordered="true" style="width: 100%; margin-top:2px;" size="small">
            <span slot="valueScope" slot-scope="text, record">
             <a-tooltip placement="top" :title="getLisenerTitle(record)" :overlayStyle="overlayStyle">
                {{text}}
              </a-tooltip>
           </span>
                    <span slot="action" slot-scope="text, record">
<!--                <a-icon type="edit" @click="updateListener(record, false)" style="padding-right: 10px"/>-->
                <a-icon type="delete" @click="listenerDel(record, false)"/>
           </span>
                </a-table>
            </a-collapse-panel>
            <a-collapse-panel key="8" v-if="isUserTask" tab="任务监听">
                <span slot="header"><a-icon type="customer-service"/> 任务监听</span>
                <a-icon slot="extra" type="plus" @click.stop="addListeners(true)"/>
                <a-table :dataSource="taskListenerData" rowKey="id" :columns="listenerColumns" :bordered="true" style="width: 100%; margin-top: 3px;" size="small">
           <span slot="valueScope" slot-scope="text, record">
              <a-tooltip placement="left" :title="getTaskLisenerTitle(record)">
                 {{text}}
              </a-tooltip>
           </span>
                    <span slot="action" slot-scope="text, record">
<!--                <a-icon type="edit" @click="updateListener(record, true)" style="padding-right: 10px"/>-->
                <a-icon type="delete" @click="listenerDel(record, true)"/>
           </span>
                </a-table>
            </a-collapse-panel>
            <a-collapse-panel key="9" v-if="isRoot">
                <span slot="header"><a-icon type="notification"/> 全局监听</span>
                <a-icon slot="extra" type="plus" @click.stop="addEventListeners(false)"/>
                <a-table :dataSource="eventListenerData" rowKey="id" :columns="eventListenerColumns" :bordered="true" style="width: 100%; margin-top:2px;" size="small">
            <span slot="valueScope" slot-scope="text, record">
              <a-tooltip placement="top" :title="getLisenerTitle(record)" :overlayStyle="overlayStyle">
                {{text}}
              </a-tooltip>
           </span>
                    <span slot="action" slot-scope="text, record">
<!--                <a-icon type="edit" @click="updateListener(record, false)" style="padding-right: 10px"/>-->
                <a-icon type="delete" @click="eventListenerDel(record, false)"/>
           </span>
                </a-table>
            </a-collapse-panel>
            <a-collapse-panel key="10" v-if="!isGateway && rootElement" tab="权限设置" style="display: none">
                <span slot="header"><a-icon type="usergroup-delete"/> 权限设置</span>
                <template slot="title">
                    <span class="el_title"></span>
                </template>
            </a-collapse-panel>
            <a-collapse-panel key="11" tab="变量设置" v-if="isCallActivity">
                <span slot="header"><a-icon type="export"/> 变量设置</span>
                <a-divider orientation="left">
                    <a-button @click.stop="addVariableSelect('in')">添加输入变量</a-button>
                </a-divider>
                <a-table :dataSource="variableData" :pagination="false" :columns="variableColumns" :bordered="true" style="width: 100%; margin-top:2px;" size="small">
            <span slot="sourceScope" slot-scope="text, record">
              <a-tooltip placement="left" :title="text" style="width:800px">
                {{text}}
              </a-tooltip>
           </span>
                    <span slot="targetScope" slot-scope="text, record">
              <a-tooltip placement="left" :title="text" style="width:800px">
                {{text}}
              </a-tooltip>
           </span>
                    <span slot="action" slot-scope="text, record,index">
               <a-icon type="edit" @click="updateViable(record,'in',index)" style="padding-right: 10px"/>
                <a-icon type="delete" @click="variableDel(record)"/>
           </span>
                </a-table>

                <a-divider orientation="left">
                    <a-button @click.stop="addVariableSelect('out')">添加输出变量</a-button>
                </a-divider>
                <a-table :dataSource="variableOutData" :pagination="false" :columns="variableColumns" :bordered="true" style="width: 100%; margin-top:2px;" size="small">
            <span slot="sourceScope" slot-scope="text, record">
              <a-tooltip placement="left" :title="text" style="width:800px">
                {{text}}
              </a-tooltip>
           </span>
                    <span slot="targetScope" slot-scope="text, record">
              <a-tooltip placement="left" :title="text" style="width:800px">
                {{text}}
              </a-tooltip>
           </span>
                    <span slot="action" slot-scope="text, record,index">
               <a-icon type="edit" @click="updateViable(record,'out',index)" style="padding-right: 10px"/>
                <a-icon type="delete" @click="outVariableDel(record)"/>
           </span>
                </a-table>
            </a-collapse-panel>
        </a-collapse>
        <!--    <div class="drawer-footer">-->
        <!--      <a-button @click="close" style="margin-right: 5px">关闭</a-button>-->
        <!--      <a-button type="primary" @click="saveXml" v-if="rootElement">保存流程</a-button>-->
        <!--    </div>-->
        <user-select ref="UserSelect" @callback="handleCallback"/>
        <role-select ref="RoleSelect" @callback="handleRoleCallback"/>
        <expressions-select ref="ExpressionsSelect" @callback="handleExpressionsCallback"></expressions-select>
        <variable-select ref="VariableSelect" @callback="handleVariableCallback"></variable-select>
        <out-variable-select ref="OutVariableSelect" @callback="handleOutVariableCallback"></out-variable-select>
        <flow-listener ref="FlowListener" @callback="handleListenerCallback"/>
        <event-listener ref="EventListener" @callback="handleEventListenerCallback"/>
        <flow-task-listener ref="FlowTaskListener" @callback="handleListenerCallback"/>
        <flow-button ref="FlowButton" @callback="handleButtonCallback"/>
    </div>
</template>

<script>
  import Vue from 'vue'
  import cmdHelper from '../CustomPanel/lib/helper/CmdHelper'
  import elementHelper from '../CustomPanel/lib/helper/ElementHelper'
  import extensionElementsHelper from '../CustomPanel/lib/helper/ExtensionElementsHelper'
  import ImplementationTypeHelper from '../CustomPanel/lib/helper/ImplementationTypeHelper'
  import UserSelect from './UserSelect'
  import RoleSelect from './RoleSelect'
  import FlowListener from './FlowListener'
  import EventListener from './EventListener'
  import FlowTaskListener from './FlowTaskListener'
  import FlowButton from './FlowButton'
  import { randomString } from '../../utils'
  import ExpressionsSelect from './ExpressionsSelect'
  import VariableSelect from './VariableSelect'
  import vcolorpicker from 'vcolorpicker'
  import moment from 'moment'
  import OutVariableSelect from './OutVariableSelect'

  Vue.use(vcolorpicker)
  export default {
    name: 'PropertyPanel',
    components: {
      OutVariableSelect,
      VariableSelect,
      ExpressionsSelect,
      UserSelect,
      RoleSelect,
      FlowListener,
      FlowTaskListener,
      FlowButton,
      EventListener,
      vcolorpicker
    },
    props: {
      modeler: {
        type: Object,
        required: true
      },
      moddleType: {
        type: String,
        required: true
      },
      processDefinitionId: {
        type: [String, Number],
        required: false
      },
      typeid: {
        type: [String, Number],
        required: false,
        default: null
      }
    },
    data() {
      return {
        labelCol: { span: 5 },
        wrapperCol: { span: 19 },
        selectedElements: [],
        userIds: [],
        optType:1,
        nodeSize: 'large',
        //备选人员
        userIds2: [],
        //备选角色
        roleIds: [],
        isRoot: false,
        //已选表达式
        expressionIds: [],
        processTypeId: null,
        isAdd: true,
        //当前选择节点
        element: {},
        //流程根节点
        rootElement: null,
        activeName: '1',
        // 人员选择的类型
        selectUserType: 'assignee',
        // 选中的代理人
        selectedAssignee: '',
        overlayStyle:{
          fontSize:"12px"
        },
        // 选中的监听器数组
        listenerData: [],
        // 监听器
        listener: {},
        //执行监听全部数据
        allListenerData:[],
        //任务监听全部数据
        allTaskListenerData:[],
        //子流程变量
        variable: {},
        outVariable: {},
        // 选中的任务监听器数组
        taskListenerData: [],
        eventListenerData: [],
        //变量数组
        variableData: [],
        //输出变量
        variableOutData: [],
        variableIndex: -1,
        // 任务监听器
        taskListener: {},
        //全局监听
        eventListener: {},
        isTaskListener: false,
        processType: [{
          value: '1',
          label: '测试流程'
        }, {
          value: '2',
          label: 'OA办公'
        }],
        userType: [{
          value: 'assignee',
          label: '指定人'
        }, {
          value: 'candidateUsers',
          label: '候选用户'
        }, {
          value: 'candidateGroups',
          label: '候选角色'
        }],
        timerEventType: [{
          value: 'timeDate',
          label: 'timeDate'
        }, {
          value: 'timeDuration',
          label: 'timeDuration'
        }, {
          value: 'timeCycle',
          label: 'timeCycle'
        }],
        scriptType: [{
          value: 'javascript',
          label: 'javascript'
        }, {
          value: 'groovy',
          label: 'groovy'
        }],
        listenerType: {
          class: '类',
          expression: '表达式',
          delegateExpression: '代理表达式'
        },
        listenerColumns: [
          {
            title: '事件',
            dataIndex: 'eventType'
          },
          {
            title: '类型',
            ellipsis: true,
            dataIndex: 'listenerType'
          },
          {
            title: '值',
            ellipsis: true,
            dataIndex: 'value',
            scopedSlots: { customRender: 'valueScope' }
          },
          {
            title: '操作',
            align: 'center',
            key: 'action',
            scopedSlots: { customRender: 'action' }
          }
        ],
        eventListenerColumns: [
          {
            title: '值',
            ellipsis: true,
            dataIndex: 'value',
            scopedSlots: { customRender: 'valueScope' }
          },
          {
            title: '操作',
            align: 'center',
            key: 'action',
            scopedSlots: { customRender: 'action' }
          }
        ],
        variableColumns: [
          {
            title: '源头',
            ellipsis: true,
            scopedSlots: { customRender: 'sourceScope' },
            dataIndex: 'source'
          },
          {
            title: '目标',
            ellipsis: true,
            scopedSlots: { customRender: 'targetScope' },
            dataIndex: 'target'
          },
          {
            title: '操作',
            key: 'action',
            align: 'center',
            scopedSlots: { customRender: 'action' }
          }
        ],
        // 按钮
        buttonsData: [],
        button: [],
        rules: {
          processKey: [{ required: true, message: '请输入流程Key', trigger: 'blur' }],
          processName: [{ required: true, message: '请输入流程名称', trigger: 'blur' }]
        },
        form: {
          id: '',
          name: '',
          taskPriority: '',
          processXml: '',
          jobPriority: '',
          candidateStarterGroups: '',
          candidateStarterUsersNames: '',
          candidateStarterUsers: '',
          historyTimeToLive: '',
          // 流程发起人
          initiator: '',
          description: '',
          resultVariableName: '',
          scriptFormat: '',
          timeDate: null
        },
        serviceTask: {
          //执行结果变量
          expressionType: 'javaClass',
          expressionValue: ''
        },
        boundaryEvent: {
          //执行结果变量
          timerType: 'timeDate'
        },
        process: {
          id: 'process_',
          processId: '',
          name: '',
          versionTag: '',
          description: ''
        },
        userTask: {
          assigneeType: '1',
          assigneeName: '',
          expressions: '',
          assignee: '',
          candidateUsersName: '',
          candidateUsers: '',
          color: '#ffffff',
          description: '',
          candidateGroups: ''
        },
        exclusiveSequence: {
          conditionExpression: ''
        },
        multiInstanceOptions: [
          {
            value: '0',
            label: '并行多重事件'
          },
          {
            value: '1',
            label: '顺序多重事件'
          }
        ],
        selectedMultiInstance: {
          isSequential: null,
          loopCardinality: '',
          collection: '',
          elementVariable: '',
          completionCondition: '',
          asyncBefore: false,
          asyncAfter: false,
          failedJobRetryTimeCycle: ''
        },
        selectedMultiInstanceNew: {
          loopCardinality: '',
          collection: '',
          elementVariable: '',
          completionCondition: ''
        },
        multiInstance: {},
        multiInstanceRules: {
          loopCardinality: [
            { required: true, message: '循环基数不能为空', trigger: 'blur' }
          ]
        }
      }
    },
    computed: {
      isEvent() {
        if (!this.element) {
          return
        }
        return this.verifyIsEvent(this.element.type)
      },
      isTask() {
        if (!this.element) {
          return
        }
        return this.verifyIsTask(this.element.type)
      },
      isUserTask() {
        if (!this.element) {
          return
        }
        return this.element.type === 'bpmn:UserTask' || this.element.type === 'bpmn:ManualTask'
      },
      isTask() {
        if (!this.element) {
          return
        }
        return this.element.type === 'bpmn:Task'
      },

      isServiceTask() {
        if (!this.element) {
          return
        }
        return this.element.type === 'bpmn:ServiceTask'
      },
      isScriptTask() {
        if (!this.element) {
          return
        }
        return this.element.type === 'bpmn:ScriptTask'
      },
      isBoundaryEvent() {
        if (!this.element) {
          return
        }
        return this.element.type === 'bpmn:BoundaryEvent'
      },
      isBusinessRuleTask() {
        if (!this.element) {
          return
        }
        return this.element.type === 'bpmn:BusinessRuleTask'
      },
      isSendTask() {
        if (!this.element) {
          return
        }
        return this.element.type === 'bpmn:SendTask'
      },
      isReceiveTask() {
        if (!this.element) {
          return
        }
        return this.element.type === 'bpmn:ReceiveTask'
      },
      isStart() {
        if (!this.element) {
          return
        }
        return this.verifyIsStart(this.element.type)
      },
      sequenceFlow() {
        if (!this.element) {
          return
        }
        return this.element.type === 'bpmn:SequenceFlow' || this.element.type === 'label'
      },
      //判断是否显示流转条件
      isExclusiveSequenceFlow() {
        if (!this.element) {
          return
        }
        const { businessObject } = this.element
        if (businessObject && businessObject.sourceRef && (businessObject.sourceRef.$type === 'bpmn:ExclusiveGateway' || businessObject.sourceRef.$type === 'bpmn:InclusiveGateway')) {
          return true
        }
        return false
      },
      //是否是网关
      isGateway() {
        if (!this.element) {
          return
        }
        return this.verifyIsGateway(this.element.type)
      },
      //是否是调用活动
      isCallActivity() {
        if (!this.element) {
          return
        }
        return this.verifyIsCallActivity(this.element.type)
      }
    },
    created() {
      this.init()
     // this.getTypes()
      //this.getListeners();
     // this.getTaskListeners();
      this.processTypeId = this.typeid
    },
    methods: {
      randomString,
      init() {
        const that = this
        this.modeler.on('selection.changed', e => {
          const { element } = e
          console.info('selection.changed', element)
          that.selectedElements = e.newSelection
          that.element = e.newSelection[0]
          //that.setDefaultProperties(that.element)
        })
        //update-begin--Author:scott  Date:20210323 for：为了适应老设计器，自定义节点的大小
        this.modeler.on('shape.added', (e) => {
          // if(e.element.type.indexOf('Task')>-1)
          // {
          //   e.element.width = 90;
          //   e.element.height = 55;
          //   e.element.y = 199;
          // }
          // if(e.element.type.indexOf('Event')>-1)
          // {
          //   e.element.width = 30;
          //   e.element.height = 30;
          // }
        })
        //update-end--Author:scott  Date:20210323 for：为了适应老设计器，自定义节点的大小

        this.modeler.on('element.changed', e => {
          //this.$emit('change',this.optType)
          const { element } = e
          console.info('element.changed', element)
          const { element: currentElement } = this
          if (!currentElement) {
            return
          }
          // 如果当前选定的元素已修改
          if (element.id === currentElement.id) {
            this.element = element
          }
        })

        this.modeler.on('canvas.viewbox.changed', e => {
          console.info('shape.move.end', e)
        })
        this.modeler.on('element.click', e => {
          const { element } = e
          let type = element.type
          console.info('element.click', element)
          this.element = element
          if (type == 'bpmn:Process') {
            //根节点点击触发
            that.rootElement = element
            that.sertProcessProperties(that.rootElement)
          } else {
            that.setDefaultProperties(element)
          }
        })
        this.modeler.on('root.added', function(e) {
          const { element } = e
          console.info('element.added', element)
          let type = element.type
          if (type == 'bpmn:Process') {
            that.rootElement = element
            //默认激活流程属性
            that.sertProcessProperties(element)
          }
        })
      },
      setOptType(optType){
        this.optType=optType;
      },
      //修改节点大小
      handleSizeChange(e) {
        if (e.target.value == 'small') {
          this.element.width = 90
          this.element.height = 55
          this.updateProperties({})
        } else {
          this.element.width = 100
          this.element.height = 80
          this.updateProperties({})
        }
      },
      getTypes() {
        this.http.get(this, {
          url: api.process.getTypes,
          success: function(me, data) {
            me.processType = data.rows
          }
        })
      },
      getListeners(typeid,callback) {
        http.get(this, {
          url: api.process.getListenersByType,
          data:{
            typeid:1
          },
          success: function (me, data) {
            me.allListenerData=data.rows
          }
        })
      },
      getTaskListeners(typeid,callback) {
        http.get(this, {
          url: api.process.getListenersByType,
          data:{
            typeid:2
          },
          success: function (me, data) {
            me.allTaskListenerData=data.rows
          }
        })
      },
      getLisenerTitle(record){
        let title=""
        this.allListenerData.forEach(row => {
          if(row.id==record.id){
            console.info("listenername",row.listenername)
            title=row.listenername
          }
        })
        return title+""+record.value
      },
      getTaskLisenerTitle(record){
        let title=""
        this.allTaskListenerData.forEach(row => {
          if(row.id==record.id){
            console.info("listenername",row.listenername)
            title=row.listenername
          }
        })
        return title+""+record.value
      },
      setFormData(formData) {
        this.$nextTick(() => {
          this.process = Object.assign({}, this.process, formData)
          this.isAdd = false
        })
      },
      //设置流程属性
      sertProcessProperties(element) {
        console.log('sertProcessProperties:element', element)
        this.isRoot = true
        if (element) {
          console.log('element.type', element.type)
          const { businessObject } = element
          // const candidateStarterUsersNames = this.process.candidateStarterUsersNames
          this.process = Object.assign({}, this.process, businessObject, businessObject.$attrs)
          //this.process.candidateStarterUsersNames = candidateStarterUsersNames
          this.setProcessUser()
          this.setListener(element, businessObject)
          //设置全局执行监听属性
          this.setEventListener(element, businessObject)
          if (businessObject.documentation && businessObject.documentation[0]) {
            this.process.description = businessObject.documentation[0].text
          }
        }
      },
      //设置节点属性
      setDefaultProperties(element) {
        console.log('setDefaultProperties:element', element)
        this.form = {}
        this.isRoot = false
        if (element) {
          console.log('element.type', element.type)
          const { businessObject } = element
          const candidateStarterUsersNames = this.form.candidateStarterUsersNames
          this.form = Object.assign({}, this.form, businessObject, businessObject.$attrs)
          //设置用户任务属性
          this.setUserTaskUser()
          //设置服务任务属性
          this.setServiceTask()
          //设置边界属性
          this.setBoundaryEventProp(element, businessObject)
          //设置执行监听属性
          this.setListener(element, businessObject)
          //设置任务监听属性
          this.setTaskListener(element, businessObject)
          //设置SequenceFlow表达式
          this.setSequenceFlow(element, businessObject)
          //设置子流程变量
          this.setCallActivity(element, businessObject)
          //设置描述
          if (businessObject.documentation[0]) {
            this.form.description = businessObject.documentation[0].text
          }
          this.buttonsData = this.button[element.id] || []
          //设置会签属性
          this.selectedMultiInstance = this.multiInstance[element.id] || {}
          this.selectedMultiInstanceNew = {}
          let loopCharacteristics = businessObject.loopCharacteristics
          if (loopCharacteristics) {
            this.selectedMultiInstance.collection = loopCharacteristics.collection
            this.selectedMultiInstanceNew.collection = loopCharacteristics.collection
            this.selectedMultiInstance.elementVariable = loopCharacteristics.elementVariable
            this.selectedMultiInstanceNew.elementVariable = loopCharacteristics.elementVariable
            if (loopCharacteristics.isSequential == true) {
              this.selectedMultiInstance.isSequential = '1'
              this.selectedMultiInstanceNew.isSequential = '1'
            } else {
              this.selectedMultiInstance.isSequential = '0'
              this.selectedMultiInstanceNew.isSequential = '0'
            }
            if (loopCharacteristics.loopCardinality) {
              this.selectedMultiInstance.loopCardinality = loopCharacteristics.loopCardinality.body
              this.selectedMultiInstanceNew.loopCardinality = loopCharacteristics.loopCardinality.body
            } else {
              this.selectedMultiInstance.loopCardinality = null
              this.selectedMultiInstanceNew.loopCardinality = null
            }
            if (loopCharacteristics.completionCondition) {
              this.selectedMultiInstance.completionCondition = loopCharacteristics.completionCondition.body
              this.selectedMultiInstanceNew.completionCondition = loopCharacteristics.completionCondition.body
            } else {
              this.selectedMultiInstance.completionCondition = null
              this.selectedMultiInstanceNew.completionCondition = null
            }
            console.info(this.selectedMultiInstance)
          }
          this.form.loopCharacteristics = null
          console.info('form', this.form)
        }
      },
      setListener(element, businessObject) {
        // 执行监听器
        this.listenerData = this.listener[element.id] || []
        if (this.listenerData.length === 0) {
          const listeners = extensionElementsHelper.getExtensionElements(businessObject, this.moddleType + ':ExecutionListener') || []
          for (let i = 0; i < listeners.length; i++) {
            const listener = listeners[i]
            const listenerType = ImplementationTypeHelper.getImplementationType(listener, this.moddleType)
            console.info('listenerType', listenerType)
            this.listenerData.push({
              //id: listener.$attrs.id,
              id: randomString(16),
              eventType: listener.event || '',
              listenerType: listenerType,
              value: listener[listenerType]
            })
          }
          this.listener[element.id] = this.listenerData
        }
      },
      setEventListener(element, businessObject) {
        // 全局监听器
        this.eventListenerData = this.eventListener[element.id] || []
        if (this.eventListenerData.length === 0) {
          const listeners = extensionElementsHelper.getExtensionElements(businessObject, this.moddleType + ':EventListener') || []
          console.info('this.eventListenerData', listeners)
          for (let i = 0; i < listeners.length; i++) {
            const listener = listeners[i]
            const listenerType = ImplementationTypeHelper.getImplementationType(listener, this.moddleType)
            this.eventListenerData.push({
              eventType: listener.event || '',
              value: listener[listenerType]
            })
          }
          this.eventListener[element.id] = this.eventListenerData
        }
      },
      setSequenceFlow(element, businessObject) {
        if (this.sequenceFlow) {
          let conditionExpression = this.form.conditionExpression
          if (conditionExpression) {
            this.exclusiveSequence.conditionExpression = conditionExpression.body
          } else {
            this.exclusiveSequence.conditionExpression = ''
          }

        }
      },
      setTaskListener(element, businessObject) {
        // 任务监听器
        this.taskListenerData = this.taskListener[element.id] || []
        if (this.taskListenerData.length === 0) {
          const listeners = extensionElementsHelper.getExtensionElements(businessObject, this.moddleType + ':TaskListener') || []
          for (let i = 0; i < listeners.length; i++) {
            const listener = listeners[i]
            const listenerType = ImplementationTypeHelper.getImplementationType(listener, this.moddleType)
            this.taskListenerData.push({
              id: randomString(16),
              eventType: listener.event || '',
              listenerType: listenerType,
              value: listener[listenerType]
            })
          }
          this.taskListener[element.id] = this.taskListenerData
        }
      },
      setProcessUser() {
        let userIds = []
        if (this.form.candidateStarterUsers) {
          userIds = this.form.candidateStarterUsers.split(',')
        }
        if (userIds.length === 0) return
        // 调用服务端接口
        // userByIds({ userIds: userIds }).then(res => {
        //   const candidateStarterUsersNames = []
        //   const candidateStarterUsers = this.form.candidateStarterUsers
        //   if (!candidateStarterUsers) return
        //   for (let i = 0; i < res.length; i++) {
        //     const user = res[i]
        //     if (candidateStarterUsers.includes(user.id)) {
        //       candidateStarterUsersNames.push(user.realName)
        //     }
        //   }
        //   this.form.candidateStarterUsersNames = candidateStarterUsersNames.join(',')
        // })
      },
      //设置用户任务属性
      setUserTaskUser() {
        if (this.isUserTask) {
          const userIds = []
          this.userTask.assigneeName = ''
          this.userTask.candidateUsersName = ''
          this.userTask.candidateGroups = ''
          this.userIds = []
          this.userIds2 = []
          this.roleIds = []
          let width = this.element.width
          if (width == 100) {
            this.nodeSize = 'large'
          } else {
            this.nodeSize = 'small'
          }
          //处理人
          let assignee = this.form.assignee
          if (assignee) {
            this.selectUserType = 'assignee'
            this.userIds = assignee.split(',')
            if (assignee.indexOf('${') > -1) {
              this.expressionIds = assignee.split(',')
            }
            this.userTask.assigneeName = this.form.assignee
          }
          //候选用户
          let candidateUsers = this.form.candidateUsers
          if (candidateUsers) {
            this.selectUserType = 'candidateUsers'
            if (candidateUsers.indexOf('${') > -1) {
              this.expressionIds = candidateUsers.split(',')
            }
            this.userTask.candidateUsersName = candidateUsers
            this.userIds2 = candidateUsers.split(',')
          }
          //候选角色
          let candidateGroups = this.form.candidateGroups
          if (candidateGroups) {
            this.selectUserType = 'candidateGroups'
            if (candidateGroups.indexOf('${') > -1) {
              this.expressionIds = candidateGroups.split(',')
            }
            this.roleIds = candidateGroups.split(',')
            this.userTask.candidateGroups = candidateGroups
          }
          if (userIds.length === 0) return
          // 调用服务端接口
          // userByIds({ userIds: userIds }).then(res => {
          //   const candidateUsersNames = []
          //   const candidateUsers = this.userTask.candidateUsers
          //   for (let i = 0; i < res.length; i++) {
          //     const user = res[i]
          //     if (this.userTask.assignee === user.id) {
          //       this.userTask.assigneeName = user.realName
          //     }
          //     if (candidateUsers.includes(user.id)) {
          //       candidateUsersNames.push(user.realName)
          //     }
          //   }
          //   if (candidateUsersNames.length > 0) {
          //     this.userTask.candidateUsersName = candidateUsersNames.join(',')
          //   }
          // })
        }
      },
      //设置服务任务属性
      setServiceTask() {
        if (this.isServiceTask) {
          if (this.form.class) {
            this.serviceTask.expressionType = 'javaClass'
            this.serviceTask.expressionValue = this.form.class
          }
          if (this.form.expression) {
            this.serviceTask.expressionType = 'javaClass'
            this.serviceTask.expressionValue = this.form.expression
          }
          if (this.form.delegateExpression) {
            this.serviceTask.expressionType = 'delegateExpression'
            this.serviceTask.expressionValue = this.form.delegateExpression
          }
        }
      },
      //设置边界事件属性
      setBoundaryEventProp() {
        let eventDefinitions = this.form.eventDefinitions
        if (eventDefinitions && eventDefinitions.length > 0) {
          let eventDefinition = eventDefinitions[0]
          if (eventDefinition.timeDate) {
            this.boundaryEvent.timerType = 'timeDate'
            this.form.timeDate = eventDefinition.timeDate.body
          }
          if (eventDefinition.timeDuration) {
            this.boundaryEvent.timerType = 'timeDuration'
            this.form.timeDate = eventDefinition.timeDuration.body
          }
          if (eventDefinition.timeCycle) {
            this.boundaryEvent.timerType = 'timeCycle'
            this.form.timeDate = eventDefinition.timeCycle.body
          }
        }
      },
      setCallActivity() {
        if (this.isCallActivity) {
          this.variableData = []
          this.variableOutData = []
          let extensionElements = this.form.extensionElements
          if (extensionElements) {
            let values = extensionElements.values
            values.forEach(row => {
              let variableType = row.$type
              if (variableType == this.moddleType + ':In') {
                this.variableData.push({
                  source: row.source,
                  target: row.target
                })
              }
              if (variableType == this.moddleType + ':Out') {
                this.variableOutData.push({
                  source: row.source,
                  target: row.target
                })
              }

            })
          }

        }
      },
      verifyIsEvent(type) {
        if (!type) return
        return type.includes('Event')
      },
      verifyIsTask(type) {
        if (!type) return
        return type.includes('Task')
      },
      verifyIsStart(type) {
        return type === 'bpmn:StartEvent'
      },
      verifyIsGateway(type) {
        if (!type) return
        return type.includes('Gateway')
      },
      verifyIsCallActivity(type) {
        if (!type) return
        return type.includes('CallActivity')
      },
      /**
       * 改变控件触发的事件
       * @param { Object } input的Event
       * @param { String } 要修改的属性的名称
       */
      changeField(event, type) {
        const value = event.target.value
        this.element[type] = value
        const properties = {}
        properties[type] = value
        if (type === 'color') {
          this.onChangeColor(value)
        }
        this.updateProperties(properties)
      },
      //设置流程名称
      updateName(e) {
        this.updateProperties({ name: e.target.value })
      },
      //设置流程Key
      updateProcessKey(e) {
        this.process.id = e.target.value
        const modeling = this.modeler.get('modeling')
        modeling.updateProperties(this.rootElement, { id: e.target.value })
      },
      //设置流程名称
      updateProcessName(e) {
        this.process.name = e.target.value
        const modeling = this.modeler.get('modeling')
        modeling.updateProperties(this.rootElement, { name: e.target.value })
      },
      updateColor(color) {
        const modeling = this.modeler.get('modeling')
        modeling.setColor(this.element, {
          stroke: 'green',
          fill: color
        })
      },
      //设置服务任务执行类型
      updateExpressionValue() {
        let expressionType = this.serviceTask.expressionType
        let expressionValue = this.serviceTask.expressionValue
        this.updateProperties({ class: null })
        this.updateProperties({ expression: null })
        this.updateProperties({ delegateExpression: null })
        if (expressionType == 'javaClass') {
          this.updateProperties({ class: expressionValue })
        }
        if (expressionType == 'expression') {
          this.updateProperties({ expression: expressionValue })
        }
        if (expressionType == 'delegateExpression') {
          this.updateProperties({ delegateExpression: expressionValue })
        }
      },
      processTypeChange(value) {
        this.processTypeId = value
      },
      //设置流程KEY
      updateKey(e) {
        this.updateProperties({ id: e.target.value })
      },
      changeEventType(event) {
        const { modeler, element } = this
        const value = event.target.value
        const bpmnReplace = modeler.get('bpmnReplace')
        this.eventType = value
        bpmnReplace.replaceElement(element, {
          type: element.businessObject.$type,
          eventDefinitionType: value
        })
      },
      changeTaskType(event) {
        const { modeler, element } = this
        const value = event.target.value
        const bpmnReplace = modeler.get('bpmnReplace')
        bpmnReplace.replaceElement(element, {
          type: value
        })
      },
      /**
       * 更新元素属性
       * @param { Object } 要更新的属性, 例如 { name: '' }
       */
      updateProperties(properties) {
        const modeling = this.modeler.get('modeling')
        modeling.updateProperties(this.element, properties)
      },
      // 流程描述设置
      updateProcessDocumentation(e) {
        let value = e.target.value
        const bpmnFactory = this.modeler.get('bpmnFactory')
        if (value) {
          const newObjectList = []
          newObjectList.push(bpmnFactory.create('bpmn:Documentation', {
            text: value
          }))
          const element = this.rootElement
          const command = cmdHelper.setList(element, element.businessObject, 'documentation', newObjectList)
          this.executeCommand(command)
        }
      },
      // 文档描述设置
      updateDocumentation(e) {
        let value = e.target.value
        const bpmnFactory = this.modeler.get('bpmnFactory')
        if (value) {
          const newObjectList = []
          newObjectList.push(bpmnFactory.create('bpmn:Documentation', {
            text: value
          }))
          const command = cmdHelper.setList(this.element, this.element.businessObject, 'documentation', newObjectList)
          this.executeCommand(command)
        }
      },
      // 条件分支设置
      updateConditionExpression() {
        if (!this.element) return
        const { businessObject } = this.element
        const bpmnFactory = this.modeler.get('bpmnFactory')
        const conditionOrConditionExpression = elementHelper.createElement(
          'bpmn:FormalExpression',
          {
            body: this.exclusiveSequence.conditionExpression
          },
          businessObject,
          bpmnFactory
        )

        const command = cmdHelper.updateBusinessObject(this.element, businessObject, {
          conditionExpression: conditionOrConditionExpression
        })
        this.executeCommand(command)
      },
      executeCommand(command) {
        const commandStack = this.modeler.get('commandStack')
        commandStack.execute(command.cmd, command.context)
      },
      handleChangeAssignee(e) {
        let value = e.target.value
        if (value === '2') {
          //this.userTask.assigneeName=''
          // this.userIds=[]
          //this.selectedAssignee = this.userTask.assignee
          // this.updateProperties({assignee: ''})
        } else {
          //this.userTask.expressions=''
          this.expressionIds = []
          //this.updateProperties({assignee:''})
        }

      },
      //打开用户选择框
      handleSelectUser(multiple, selectUserType) {
        this.selectUserType = selectUserType
        const _this = this.$refs.UserSelect
        _this.multiple = multiple
        if (multiple) {
          _this.selectedKeys = this.userIds2
        } else {
          _this.selectedKeys = this.userIds
        }
        _this.show()
      },
      //打开角色选择框
      handleSelectRoles(multiple, selectUserType) {
        this.selectUserType = selectUserType
        const _this = this.$refs.RoleSelect
        _this.multiple = multiple
        _this.selectedKeys = this.roleIds
        _this.show()
      },
      //打开表达式选择框
      handleSelectExpressions(multiple, selectUserType) {
        this.selectUserType = selectUserType
        const _this = this.$refs.ExpressionsSelect
        _this.multiple = multiple
        _this.selectedKeys = this.expressionIds
        _this.show()
      },

      //用户选择回调
      handleCallback(selectedRows, selectedKeys) {
        this.clearSelect()
        if (selectedRows && selectedRows.length > 0) {
          const userIds = []
          const userNames = []
          for (let i = 0; i < selectedRows.length; i++) {
            userIds.push(selectedRows[i].id)
            userNames.push(selectedRows[i].id)
          }
          if (this.selectUserType === 'candidateStarterUsers') {
            this.form.candidateStarterUsers = selectedKeys.join(',')
            this.form.candidateStarterUsersNames = selectedKeys.join(',')
            this.updateProperties({ candidateStarterUsers: this.form.candidateStarterUsers })
          }
          if (this.selectUserType === 'assignee') {
            this.userIds = selectedKeys
            this.userTask.assignee = selectedKeys.join(',')
            this.userTask.assigneeName = selectedKeys.join(',')
            this.updateProperties({ assignee: this.userTask.assignee })
          }
          if (this.selectUserType === 'candidateUsers') {
            this.userIds2 = selectedKeys
            this.userTask.candidateUsers = selectedKeys.join(',')
            this.userTask.candidateUsersName = selectedKeys.join(',')
            this.updateProperties({ candidateUsers: this.userTask.candidateUsers })
          }
          this.$forceUpdate()
        }
      },
      //角色选择回调
      handleRoleCallback(selectedRows, selectedKeys) {
        this.clearSelect()
        if (selectedRows && selectedRows.length > 0) {
          const roleIds = []
          for (let i = 0; i < selectedRows.length; i++) {
            roleIds.push(selectedRows[i].id)
          }
          this.roleIds = selectedKeys
          this.userTask.candidateGroups = selectedKeys.join(',')
          this.updateProperties({ candidateGroups: this.userTask.candidateGroups })
        }
      },
      //清空人员角色表达式选择
      clearSelect() {
        this.userIds = []
        this.userIds2 = []
        this.roleIds = []
        this.expressionIds = []
        this.userTask.assigneeName = ''
        this.userTask.candidateUsersName = ''
        this.userTask.candidateGroups = ''
        this.updateProperties({ assignee: null })
        this.updateProperties({ candidateUsers: null })
        this.updateProperties({ candidateGroups: null })
      },
      //表达式更新
      handleExpressionsUpdate(e) {
        this.userTask.expressions = e.target.value
        this.userTask.assigneeName = e.target.value
        this.updateProperties({ assignee: this.userTask.expressions })
      },
      //角色更新
      handleRoleChange(e) {
        let value = e.target.value
        if (value) {
          this.userTask.candidateGroups = value
          this.updateProperties({ candidateGroups: value })
        } else {
          this.roleIds = []
          this.updateProperties({ candidateGroups: null })
        }
      },
      //处理人更新
      handleUserChange(e) {
        let value = e.target.value
        if (value) {
          this.userTask.assignee = value
          this.updateProperties({ assignee: value })
        } else {
          this.userIds = []
          this.updateProperties({ assignee: null })
        }
      },
      //候选用户更新
      handleUsersChange(e) {
        let value = e.target.value
        if (value) {
          this.userTask.candidateUsers = value
          this.updateProperties({ candidateUsers: value })
        } else {
          this.userIds2 = []
          this.updateProperties({ candidateUsers: null })
        }
      },
      //表达式选择回调
      handleExpressionsCallback(selectedRows) {
        if (selectedRows && selectedRows.length > 0) {
          this.clearSelect()
          const expressionIds = []
          const expressions = []
          for (let i = 0; i < selectedRows.length; i++) {
            expressionIds.push(selectedRows[i].id)
            expressions.push(selectedRows[i].expression)
          }
          this.expressionIds = expressionIds
          this.userTask.expressions = expressions.join(',')
          if (this.selectUserType === 'assignee') {
            this.userTask.assigneeName = expressions.join(',')
            this.updateProperties({ assignee: this.userTask.expressions })
          }
          if (this.selectUserType === 'candidateUsers') {
            this.userTask.candidateUsersName = expressions.join(',')
            this.updateProperties({ candidateUsers: this.userTask.expressions })
          }
          if (this.selectUserType === 'candidateGroups') {
            this.userTask.candidateGroups = expressions.join(',')
            this.updateProperties({ candidateGroups: this.userTask.expressions })
          }
        }
      },
      //设置表单key
      updateFormKey(e) {
        this.updateProperties({ formKey: e.target.value })
      },
      //打开监听选择器弹框
      addListeners(isTaskListener) {
        this.isTaskListener = isTaskListener
        let _this = this.$refs.FlowListener
        if (isTaskListener) {
          _this = this.$refs.FlowTaskListener
        }
        _this.multiple = true
        _this.selectedKeys = []
        _this.show()
      },
      //打开全局监听器弹窗
      addEventListeners() {
        let _this = this.$refs.EventListener
        _this.multiple = true
        _this.selectedKeys = []
        _this.show()
      },
      //打开全局监听器弹窗回调
      handleEventListenerCallback(val, activeKey) {
        const bpmnFactory = this.modeler.get('bpmnFactory')
        let element = this.isRoot ? this.rootElement : this.element
        const bo = element.businessObject
        let type = ''
        let data
        // 全局监听器
        type = this.moddleType + ':EventListener'
        for (let i = 0; i < this.eventListenerData.length; i++) {
          data = this.eventListenerData[i]
          if (data.id === val.id) {
            this.eventListenerDel(data)
            break
          }
        }
        this.eventListenerData.push(val)
        this.eventListenerData[element.id] = this.eventListenerData

        let extensionElements = bo.extensionElements
        if (!extensionElements) {
          //当扩展元素(bpmn2:extensionElement)不存在时创建
          extensionElements = elementHelper.createElement('bpmn:ExtensionElements', { values: [] }, bo, bpmnFactory)
          this.executeCommand(cmdHelper.updateBusinessObject(element, bo, { extensionElements: extensionElements }))
        }
        this.executeCommand(this.createEventExtensionElement(element, type, extensionElements, val, bpmnFactory))
      },
      //监听选择回调
      handleListenerCallback(val, activeKey) {
        const bpmnFactory = this.modeler.get('bpmnFactory')
        let element = this.isRoot ? this.rootElement : this.element
        const bo = element.businessObject
        let type = ''
        let data
        // 执行监听器
        if (!this.isTaskListener) {
          type = this.moddleType + ':ExecutionListener'
          for (let i = 0; i < this.listenerData.length; i++) {
            data = this.listenerData[i]
            if (data.id === val.id) {
              this.listenerDel(data)
              break
            }
          }
          this.listenerData.push(val)
          this.listener[element.id] = this.listenerData
        } else {
          //任务监听器
          type = this.moddleType + ':TaskListener'
          for (let i = 0; i < this.taskListenerData.length; i++) {
            data = this.taskListenerData[i]
            if (data.id === val.id) {
              this.listenerDel(data)
              break
            }
          }
          this.taskListenerData.push(val)
          this.taskListener[element.id] = this.taskListenerData
        }
        let extensionElements = bo.extensionElements
        if (!extensionElements) {
          //当扩展元素(bpmn2:extensionElement)不存在时创建
          extensionElements = elementHelper.createElement('bpmn:ExtensionElements', { values: [] }, bo, bpmnFactory)
          this.executeCommand(cmdHelper.updateBusinessObject(element, bo, { extensionElements: extensionElements }))
        }
        this.executeCommand(this.createExtensionElement(element, type, extensionElements, val, bpmnFactory))
      },
      // 创建监听扩展元素
      createExtensionElement(element, type, extensionElements, value, bpmnFactory) {
        const props = {
          event: value.eventType,
          id:value.id
        }
        props[value.listenerType == 'javaClass' ? 'class' : value.listenerType] = value.value
        const newElem = elementHelper.createElement(type, props, extensionElements, bpmnFactory)
        return cmdHelper.addElementsTolist(element, extensionElements, 'values', [newElem])
      },

      // 创建变量扩展元素
      createExtensionElement2(element, type, extensionElements, value, bpmnFactory) {
        const props = {
          source: value.source,
          target: value.target
        }
        const newElem = elementHelper.createElement(type, props, extensionElements, bpmnFactory)
        return cmdHelper.addElementsTolist(element, extensionElements, 'values', [newElem])
      },
      // 创建全局监听扩展元素
      createEventExtensionElement(element, type, extensionElements, value, bpmnFactory) {
        const props = {}
        props[value.listenerType == 'javaClass' ? 'class' : value.listenerType] = value.value
        const newElem = elementHelper.createElement(type, props, extensionElements, bpmnFactory)
        return cmdHelper.addElementsTolist(element, extensionElements, 'values', [newElem])
      },
      // 删除扩展元素
      removeExtensionElement(element, bo, type, idx) {
        const listeners = extensionElementsHelper.getExtensionElements(bo, type) || []
        const listener = listeners[idx]
        if (listener) {
          return extensionElementsHelper.removeEntry(bo, element, listener)
        }
      },
      updateListener(data, isTaskListener) {
        this.isTaskListener = isTaskListener
        let _this = this.$refs.FlowListener
        if (isTaskListener) {
          _this = this.$refs.FlowTaskListener
        }
        _this.form = {
          ...data
        }
        _this.dialog = true
      },

      listenerDel(val, isTaskListener) {
        this.isTaskListener = isTaskListener
        let idx
        let type
        const element = this.isRoot ? this.rootElement : this.element
        const bo = element.businessObject
        // 执行监听器
        if (!isTaskListener) {
          idx = this.listenerData.indexOf(val)
          this.listenerData.splice(idx, 1)
          type = this.moddleType + ':ExecutionListener'
        } else {
          idx = this.taskListenerData.indexOf(val)
          this.taskListenerData.splice(idx, 1)
          type = this.moddleType + ':TaskListener'
        }
        this.executeCommand(this.removeExtensionElement(element, bo, type, idx))
      },
      //删除全局监听
      eventListenerDel(val) {
        let idx
        let type
        const element = this.isRoot ? this.rootElement : this.element
        const bo = element.businessObject
        idx = this.eventListenerData.indexOf(val)
        this.eventListenerData.splice(idx, 1)
        type = this.moddleType + ':EventListener'

        this.executeCommand(this.removeExtensionElement(element, bo, type, idx))
      },
      updateViable(data, variableType, index) {
        this.variableIndex = index
        let _this = this.$refs.VariableSelect
        if (variableType == 'out') {
          _this = this.$refs.OutVariableSelect
        }
        _this.form = {
          ...data
        }
        _this.show(false)
      },
      variableDel(val) {
        const bo = this.element.businessObject
        let type = this.moddleType + ':In'
        let idx = this.variableData.indexOf(val)
        this.variableData.splice(idx, 1)
        this.executeCommand(this.removeExtensionElement(this.element, bo, type, idx))
      },
      //删除输出变量
      outVariableDel(val) {
        const bo = this.element.businessObject
        let type = this.moddleType + ':Out'
        let idx = this.variableOutData.indexOf(val)
        this.variableOutData.splice(idx, 1)
        this.executeCommand(this.removeExtensionElement(this.element, bo, type, idx))
      },
      addVariableSelect(variableType) {
        this.variableIndex = -1
        let _this = this.$refs.VariableSelect
        if (variableType == 'out') {
          _this = this.$refs.OutVariableSelect
        }
        _this.multiple = true
        _this.selectedKeys = []
        _this.show(true)
      },
      //选择变量回调
      handleVariableCallback(val, activeKey) {
        const bpmnFactory = this.modeler.get('bpmnFactory')
        const bo = this.element.businessObject
        let data
        let type = this.moddleType + ':In'
        for (let i = 0; i < this.variableData.length; i++) {
          data = this.variableData[i]
          if (data.id === val.id || (data.source == val.source && data.target == val.target) || (this.variableIndex == i)) {
            //属性存在时删除属性
            this.variableDel(data)
            break
          }
        }
        this.variableData.push(val)
        this.variable[this.element.id] = this.variableData
        let extensionElements = bo.extensionElements
        if (!extensionElements) {
          extensionElements = elementHelper.createElement('bpmn:ExtensionElements', { values: [] }, bo, bpmnFactory)
          this.executeCommand(cmdHelper.updateBusinessObject(this.element, bo, { extensionElements: extensionElements }))
        }
        this.executeCommand(this.createExtensionElement2(this.element, type, extensionElements, val, bpmnFactory))
      },

      //输出变量回调
      handleOutVariableCallback(val, activeKey) {
        const bpmnFactory = this.modeler.get('bpmnFactory')
        const bo = this.element.businessObject
        let data
        let type = this.moddleType + ':Out'
        for (let i = 0; i < this.variableOutData.length; i++) {
          data = this.variableOutData[i]
          if (data.id === val.id || (data.source == val.source && data.target == val.target) || (this.variableIndex == i)) {
            //属性存在时删除属性
            this.outVariableDel(data)
            break
          }
        }
        this.variableOutData.push(val)
        this.outVariable[this.element.id] = this.variableOutData
        let extensionElements = bo.extensionElements
        if (!extensionElements) {
          extensionElements = elementHelper.createElement('bpmn:ExtensionElements', { values: [] }, bo, bpmnFactory)
          this.executeCommand(cmdHelper.updateBusinessObject(this.element, bo, { extensionElements: extensionElements }))
        }
        this.executeCommand(this.createExtensionElement2(this.element, type, extensionElements, val, bpmnFactory))
      },

      addButton() {
        const _this = this.$refs.FlowButton
        _this.multipleSelection = this.buttonsData
        this.buttonsData.forEach(row => {
          _this.$refs.multipleTable.toggleRowSelection(row)
        })
        _this.dialog = true
      },
      handleButtonCallback(datas) {
        this.buttonsData = datas
        const bpmnFactory = this.modeler.get('bpmnFactory')
        const bo = this.element.businessObject
        let extensionElements = bo.extensionElements
        if (!extensionElements) {
          extensionElements = elementHelper.createElement('bpmn:ExtensionElements', { values: [] }, bo, bpmnFactory)
          this.executeCommand(cmdHelper.updateBusinessObject(this.element, bo, { extensionElements: extensionElements }))
        }
        const newElems = []
        if (this.buttonsData) {
          for (let i = 0; i < this.buttonsData.length; i++) {
            const button = this.buttonsData[i]
            const props = {
              name: button.name,
              code: button.action
            }
            const newElem = elementHelper.createElement(this.moddleType + ':Button', props, extensionElements, bpmnFactory)
            newElems.push(newElem)
          }
        }

        this.executeCommand(cmdHelper.addElementsTolist(this.element, extensionElements, 'values', newElems))
      },

      removeButton(data) {
        const idx = this.buttonsData.indexOf(data)
        const type = this.moddleType + ':Button'
        this.buttonsData.splice(idx, 1)
        const bo = this.element.businessObject
        this.executeCommand(this.removeExtensionElement(this.element, bo, type, idx))
      },
      //会签类型选择回调
      handleMultiInstance(val) {
        this.multiInstance[this.element.id] = this.selectedMultiInstance
        this.selectedMultiInstance = {}
        let loopCharacteristics = {}
        if (val === '') {
          loopCharacteristics = undefined
        } else {
          const moddle = this.modeler.get('moddle')
          loopCharacteristics = moddle.create('bpmn:MultiInstanceLoopCharacteristics')
          if (val === '1') {
            loopCharacteristics.isSequential = true
          }
        }
        this.updateProperties({
          loopCharacteristics: loopCharacteristics
        })
        //一下方法为更新xml属性
        if (this.selectedMultiInstanceNew.loopCardinality) {
          this.updateFormalExpression('loopCardinality', this.selectedMultiInstanceNew.loopCardinality)
        }
        if (this.selectedMultiInstanceNew.collection) {
          this.updateMultiInstanceProperty(this.moddleType + ':collection', this.selectedMultiInstanceNew.collection)
        }
        if (this.selectedMultiInstanceNew.elementVariable) {
          this.updateMultiInstanceProperty(this.moddleType + ':elementVariable', this.selectedMultiInstanceNew.elementVariable)
        }
        if (this.selectedMultiInstanceNew.completionCondition) {
          this.updateFormalExpression('completionCondition', this.selectedMultiInstanceNew.completionCondition)
        }
      },
      updateFormalExpression(propertyName, newValue) {
        const bpmnFactory = this.modeler.get('bpmnFactory')
        const bo = this.element.businessObject
        const loopCharacteristics = bo.loopCharacteristics

        const expressionProps = {}

        if (!newValue) {
          // remove formal expression
          expressionProps[propertyName] = undefined
          this.executeCommand(cmdHelper.updateBusinessObject(this.element, loopCharacteristics, expressionProps))
          return
        }

        const existingExpression = loopCharacteristics.get(propertyName)

        if (!existingExpression) {
          // add formal expression
          expressionProps[propertyName] = elementHelper.createElement('bpmn:FormalExpression', { body: newValue }, parent, bpmnFactory)
          this.executeCommand(cmdHelper.updateBusinessObject(this.element, loopCharacteristics, expressionProps))
          return
        }

        // edit existing formal expression
        this.executeCommand(cmdHelper.updateBusinessObject(this.element, existingExpression, {
          body: newValue
        }))
      },
      updateMultiInstanceProperty(type, value) {
        const bo = this.element.businessObject
        const loopCharacteristics = bo.loopCharacteristics
        const pros = {}
        pros[type] = value || undefined
        this.executeCommand(cmdHelper.updateBusinessObject(this.element, loopCharacteristics, pros))
      },
      //脚本类型选择事件
      scriptTypeChange(value) {
        this.form.scriptFormat = value
        this.updateProperties({ scriptFormat: value })
      },
      //脚本内容设置
      updateScript(e) {
        this.updateProperties({ script: e.target.value })
      },
      //边界时间时间选择
      timerEventTypeChange() {

        const bpmnFactory = this.modeler.get('bpmnFactory')
        const bo = this.element.businessObject
        let eventDefinitions = bo.eventDefinitions
        const newElems = []
        let obj = elementHelper.createElement('bpmn:Expression', { body: this.form.timeDate }, eventDefinitions, bpmnFactory)
        const props = {}
        props[this.boundaryEvent.timerType] = obj
        const newElem = elementHelper.createElement('bpmn:TimerEventDefinition', props, bo, bpmnFactory)
        newElems.push(newElem)
        this.executeCommand(cmdHelper.updateBusinessObject(this.element, bo, { eventDefinitions: newElems }))
      },
      close() {
        this.$emit('callback')
      },
      //保存xml
      async saveXml() {
        const result = await this.modeler.saveXML({ format: false })
        const { xml } = result
        const bo = this.rootElement.businessObject
        let flowElements = bo.flowElements
        let nodes = ''
        flowElements.forEach((item, index) => {
          let type = item.$type
          if (type.indexOf('Task') > -1) {
            nodes += 'id=' + item.id + '###nodeName=' + item.name + '@@@'
          }
        })
        this.$refs['processForm'].validate(valid => {
          if (valid) {
            try {
              this.process.processXml = xml
              this.process.processKey = this.process.id
              this.process.id = this.process.processId
              this.process.processName = this.process.name
              this.http.saveOrUpdate(this, {
                api: this.api.process,
                data: this.process,
                success: function(me, data) {
                  me.$message.success('保存成功')
                  me.$emit('callback')
                }
              })
            } catch (err) {
              console.log(err)
            }

          } else {
            return false
          }
        })
      }
    }
  }
</script>

<style lang="scss">
    .property-panel {

    }

    .overlayClassName {
        div {
            width: 340px;
            z-index: 9999
        }
    }

    .el_title {
        padding-left: 20px;
    }

    .el_input {
        width: 280px;
    }
</style>
